package com.zhaoxi.project.hrp.service;

import com.zhaoxi.common.utils.DictUtils;
import com.zhaoxi.common.utils.SecurityUtils;
import com.zhaoxi.framework.security.LoginUser;
import com.zhaoxi.framework.security.service.TokenService;
import com.zhaoxi.framework.web.BaseService;
import com.zhaoxi.project.hrp.domain.HrpPartner;
import com.zhaoxi.project.hrp.domain.SysRole;
import com.zhaoxi.project.hrp.domain.SysTenant;
import com.zhaoxi.project.hrp.domain.SysUser;
import com.zhaoxi.project.hrp.mapper.SysTenantMapper;
import com.zhaoxi.project.hrp.service.impl.HrpPartnerServiceImpl;
import com.zhaoxi.project.sys.domain.*;
import com.zhaoxi.project.sys.service.impl.SysConfigServiceImpl;
import com.zhaoxi.project.sys.service.impl.SysDictDataServiceImpl;
import com.zhaoxi.project.sys.service.impl.SysDictTypeServiceImpl;
import com.zhaoxi.project.sys.service.impl.SysMenuServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 租户Service业务层处理
 *
 * @author zhaoxi
 * @date 2023-11-22
 */
@Service
public class SysTenantServiceImpl extends BaseService {
    @Autowired
    private SysTenantMapper sysTenantMapper;
    @Autowired
    private HrpPartnerServiceImpl hrpPartnerService;
    @Autowired
    private UserService sysUserService;
    @Autowired
    private SysMenuServiceImpl sysMenuService;
    @Autowired
    private SysRoleServiceImpl sysRoleService;
    @Autowired
    private SysDeptServiceImpl sysDeptService;
    @Autowired
    private SysDictTypeServiceImpl sysDictTypeService;
    @Autowired
    private SysDictDataServiceImpl sysDictDataService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SysConfigServiceImpl sysConfigService;

    /**
     * 1-1、查询租户详细信息
     *
     * @param tenantId 租户主键
     * @return 租户
     */

    public SysTenant selectSysTenantByTenantId(Long tenantId) {
        return sysTenantMapper.selectSysTenantByTenantId(tenantId);
    }

    /**
     * 1-2、查询租户列表
     *
     * @param sysTenant 租户
     * @return 租户
     */

    public List<SysTenant> selectSysTenantList(SysTenant sysTenant) {
        return sysTenantMapper.selectSysTenantList(sysTenant);
    }

    /**
     * 2-1、以管理员身份新增租户
     *
     * @param sysTenant 租户
     * @return 结果
     */
    @Transactional
    public int insertSysTenant(SysTenant sysTenant) {
        //保存管理员的租户id
        Long adminTenantId = getTenantId();
        // 总共更新 10 张表
        // 1、更新基表 hrp_partner ，将id赋值给租户id
        HrpPartner hrpPartner = new HrpPartner();
        hrpPartner.setName(sysTenant.getTenantName());
        hrpPartner.setMobile(sysTenant.getMobile());
        hrpPartner.setIsCustomer("0");
        hrpPartnerService.insertHrpPartner(hrpPartner);
        Long tenantId = hrpPartner.getId();//拿到租户id
        hrpPartner.setTenantId(tenantId);
        hrpPartnerService.updateHrpPartner(hrpPartner);
        // 2、更新租户表 sys_tenant，切换租户id
        sysTenant.setTenantId(tenantId);
        sysTenant.setCreateBy(getUsername());
        changeTenantId(tenantId);
        int r = sysTenantMapper.insertSysTenant(sysTenant);
        // 3、更新用户表 sys_user
        SysUser sysUser = new SysUser();
        sysUser.setUserId(tenantId);
        sysUser.setTenantId(tenantId);
        sysUser.setLoginName(sysTenant.getLoginName());
        //sysUser.setPassword(SecurityUtils.encryptPassword(sysTenant.getPassword()));
        sysUser.setPassword(sysTenant.getPassword());
        sysUser.setCreateBy(getUsername());
        sysUserService.insertUser(sysUser);
        // 4、更新菜单表 sys_menu
        /*SysMenu menu = new SysMenu();
        menu.setTenantId(adminTenantId);//理论上预留菜单版本位置
        List<SysMenu> menuList = sysMenuService.selectMenuList(sysUser.getUserId());
        for (SysMenu m : menuList) {
            m.setTenantId(tenantId);
        }
        sysMenuService.buildMenuTree2(menuList);// 创建树结构菜单成功*/
        // 5、更新角色表 sys_role
        /*SysRole sysRole = new SysRole();
        sysRole.setTenantId(tenantId);
        sysRole.setRoleName("租户管理员_" + tenantId);
        sysRole.setRoleKey("admin_" + tenantId);
        sysRole.setRoleSort(0);
        sysRole.setMenuCheckStrictly(true);
        sysRole.setDeptCheckStrictly(true);
        sysRole.setStatus("0");
        sysRole.setDelFlag("0");
        sysRole.setCreateBy(getUsername());*/

        // 6、通过赋值 menuIds 属性更新角色-菜单关联表 sys_role_menu
        /*Long[] menuIds = sysMenuService.getMenuIdsByTenantId(tenantId);
        sysRole.setMenuIds(menuIds);
        sysRoleService.insertRole(sysRole);*/
        
        // 同步系统配置表 sys_config
        changeTenantId(adminTenantId);// 切换管理员id，同步平台配置参数
        SysConfig sysConfig = new SysConfig();
        sysConfig.setTenantId(adminTenantId);
        List<SysConfig> sysConfigs = sysConfigService.selectConfigList(sysConfig);
        // 当没有需要同步的系统配置参数时，则跳过同步步骤
        if(sysConfigs.size() != 0) {
            for (SysConfig config : sysConfigs) {
                config.setConfigKey(config.getConfigKey());
                config.setTenantId(tenantId);
            }
            sysConfigService.batchSysConfig(sysConfigs);
        }

        // 7、更新用户与角色关联表 sys_user_role
        changeTenantId(tenantId);// 切换租户id
        String initRole = sysConfigService.selectConfigByKey("sys.tenant.initRole");// 从配置文件获取租户初始化角色值
        // 将角色值解析为角色ID
        Long initRoleId = null;
        try {
            initRoleId = Long.parseLong(initRole);
        } catch (NumberFormatException ex) {
            ex.printStackTrace();
        }
        SysRole sysRole = sysRoleService.selectRoleById(initRoleId);
        Long[] sysRoleIds = {sysRole.getRoleId()};
        sysUser.setRoleIds(sysRoleIds);
        //sysUser.setRoleIds(new Long[]{sysRole.getRoleId()});
        sysUserService.insertUserRole(sysUser);
        // 8、更新部门表sys_dept，初始化总公司以新建下属部门
        /*SysDept sysDept = new SysDept();
        sysDept.setTenantId(tenantId);
        sysDept.setDeptName(sysTenant.getDeptName());
        sysDept.setParentId(0L);
        sysDept.setAncestors("0");
        sysDept.setOrderNum(0);
        sysDept.setPhone(sysTenant.getMobile());
        sysDept.setStatus("0");
        sysDept.setDelFlag("0");
        sysDept.setCreateBy(getUsername());
        sysDeptService.insertCompany(sysDept);*/
        // 9、更新字典类型表 sys_dict_type
        SysDictType sysDictType = new SysDictType();
        sysDictType.setTenantId(adminTenantId);
        List<SysDictType> dictTypes = sysDictTypeService.selectSyncDictTypeList(sysDictType);
        for (SysDictType dictType : dictTypes) {
            dictType.setTenantId(tenantId);
        }
        sysDictTypeService.batchSysDictType(dictTypes);
        // 10、更新字典数据表 sys_dict_data
        /*SysDictData sysDictData = new SysDictData();
        sysDictData.setTenantId(adminTenantId);
        List<SysDictData> dictDatas = sysDictDataService.selectDictDataList(sysDictData);
        for (SysDictData dictData : dictDatas) {
            dictData.setTenantId(tenantId);
        }
        sysDictDataService.batchSysDictData(dictDatas);*/
        sysDictTypeService.loadingDictCache();//刷新缓存
        changeTenantId(adminTenantId);//租户id切换回来
        return r;
    }

    /**
     * 2-1、以普通人身份新增租户
     *
     * @param sysUser 普通人
     * @return 结果
     */
    @Transactional
    public int insertSysTenantByCom(SysUser sysUser) {
        //自定义管理员的租户id
        Long adminTenantId = 1L;
        // 总共更新 10 张表
        // 1、更新基表 hrp_partner ，将id赋值给租户id
        HrpPartner hrpPartner = new HrpPartner();
        hrpPartner.setName(sysUser.getLoginName());// 用户即租户
        hrpPartner.setIsCustomer("0");
        hrpPartnerService.insertHrpPartner(hrpPartner);
        Long tenantId = hrpPartner.getId();//拿到租户id
        hrpPartner.setTenantId(tenantId);
        hrpPartnerService.updateHrpPartner(hrpPartner);
        // 2、更新租户表 sys_tenant，切换租户id
        SysTenant sysTenantWithUser = new SysTenant();
        sysTenantWithUser.setEnableFlag("1");
        sysTenantWithUser.setTenantId(tenantId);
        sysTenantWithUser.setCreateBy(sysUser.getLoginName());
        sysTenantWithUser.setTenantName(sysUser.getLoginName());
        //changeTenantId(tenantId);
        int r = sysTenantMapper.insertSysTenant(sysTenantWithUser);
        // 3、更新用户表 sys_user
        sysUser.setUserId(tenantId);
        sysUser.setTenantId(tenantId);
        sysUser.setLoginName(sysUser.getLoginName());
        sysUser.setUserName(sysUser.getUserName());
        //sysUser.setPassword(SecurityUtils.encryptPassword(sysTenant.getPassword()));
        //sysUser.setPassword(sysTenant.getPassword());
        sysUser.setCreateBy(sysUser.getLoginName());
        //sysUserService.insertUser(sysUser);
//        sysUserService.insertUser1(sysUser);

        // 同步系统配置表 sys_config
        //changeTenantId(adminTenantId);// 切换管理员id，同步平台配置参数
        SysConfig sysConfig = new SysConfig();
        sysConfig.setTenantId(adminTenantId);
        List<SysConfig> sysConfigs = sysConfigService.selectConfigList(sysConfig);
        // 当没有需要同步的系统配置参数时，则跳过同步步骤
        if(sysConfigs.size() != 0) {
            for (SysConfig config : sysConfigs) {
                config.setConfigKey(config.getConfigKey());
                config.setTenantId(tenantId);
            }
            sysConfigService.batchSysConfig(sysConfigs);
        }

        // 7、更新用户与角色关联表 sys_user_role
        //changeTenantId(tenantId);// 切换租户id
        String initRole = sysConfigService.selectConfigByTenantKeyAndId("sys.tenant.initRole", tenantId);// 从配置文件获取租户初始化角色值
        // 将角色值解析为角色ID
        Long initRoleId = null;
        try {
            initRoleId = Long.parseLong(initRole);
        } catch (NumberFormatException ex) {
            ex.printStackTrace();
        }
        SysRole sysRole = sysRoleService.selectRoleById(initRoleId);
        Long[] sysRoleIds = {sysRole.getRoleId()};
        sysUser.setRoleIds(sysRoleIds);
        //sysUser.setRoleIds(new Long[]{sysRole.getRoleId()});
        sysUserService.insertUserRole(sysUser);
        
        // 9、更新字典类型表 sys_dict_type
        SysDictType sysDictType = new SysDictType();
        sysDictType.setTenantId(adminTenantId);
        List<SysDictType> dictTypes = sysDictTypeService.selectSyncDictTypeList(sysDictType);
        for (SysDictType dictType : dictTypes) {
            dictType.setTenantId(tenantId);
        }
        sysDictTypeService.batchSysDictType(dictTypes);
        // 10、更新字典数据表 sys_dict_data
        /*SysDictData sysDictData = new SysDictData();
        sysDictData.setTenantId(adminTenantId);
        List<SysDictData> dictDatas = sysDictDataService.selectDictDataList(sysDictData);
        for (SysDictData dictData : dictDatas) {
            dictData.setTenantId(tenantId);
        }
        sysDictDataService.batchSysDictData(dictDatas);*/
        //sysDictTypeService.loadingDictCache();//刷新缓存
        //changeTenantId(adminTenantId);//租户id切换回来
        return r;
    }

    /**
     * 3-1、修改租户
     *
     * @param sysTenant 租户
     * @return 结果
     */

    public int updateSysTenant(SysTenant sysTenant) {
        return sysTenantMapper.updateSysTenant(sysTenant);
    }

    /**
     * 4-1、批量删除租户
     *
     * @param tenantIds 需要删除的租户主键
     * @return 结果
     */

    //public int deleteSysTenantByTenantIds(Long[] tenantIds) {
    //    return sysTenantMapper.deleteSysTenantByTenantIds(tenantIds);
    //}

    /**
     * 4-2、删除租户信息
     *
     * @param tenantId 租户主键
     * @return 结果
     */
    @Transactional
    public int deleteSysTenantByTenantIds(Long tenantId) {
        //保存管理员的租户id
        Long adminTenantId = getTenantId();
        //1、删除角色，同步删除角色-菜单表，角色-部门表，角色表共3张表
        Long[] roleIds = sysRoleService.selectRoleIdsByTenant(tenantId);
        if(roleIds.length != 0) {
            sysRoleService.deleteRoleByIdsDiretly(roleIds);
        }
        //2、删除用户，同步删除用户-角色表，用户-部门表，用户表共3张表
        Long[] userIds = sysUserService.selectUserIdsByTenant(tenantId);
        for (Long userId : userIds) {
            sysUserService.deleteUserById(userId);
        }
        //3、删除菜单
        sysMenuService.deleteMenuByTenantId(tenantId);
        //4、先删除缓存
        SysDictType dictType = new SysDictType();
        dictType.setTenantId(tenantId);
        changeTenantId(tenantId);
        List<SysDictType> sysDictTypes = sysDictTypeService.selectDictTypeList(dictType);
        for (SysDictType d : sysDictTypes) {
            DictUtils.removeDictCache(d.getDictType() + "_" + tenantId);
        }
        //5、删除字典数据，字典类型
        sysDictDataService.deleteDictDataByTenantId(tenantId);
        sysDictTypeService.deleteDictTypeByTenantId(tenantId);
        //6、删除基表（客户表）
        hrpPartnerService.deleteHrpPartnerByTenantId(tenantId);
        //7、删除租户
        changeTenantId(adminTenantId);
        return sysTenantMapper.deleteSysTenantByTenantId(tenantId);
    }

    /**
     * 5-1、切换租户id
     *
     * @param tenantId 租户主键
     * @return 结果
     */
    public String changeTenantId(Long tenantId) {
        Long userId = SecurityUtils.getUserId();
        if (!SecurityUtils.isAdmin(userId)) {
            return "只有超级管理员可以切换租户!";
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        loginUser.setTenantId(tenantId);
        tokenService.setLoginUser(loginUser);
        return "切换租户成功!已切换到" + loginUser.getUsername();
    }
}
